/*******************************************************************************
 *     ___                  _   ____  ____
 *    / _ \ _   _  ___  ___| |_|  _ \| __ )
 *   | | | | | | |/ _ \/ __| __| | | |  _ \
 *   | |_| | |_| |  __/\__ \ |_| |_| | |_) |
 *    \__\_\\__,_|\___||___/\__|____/|____/
 *
 *  Copyright (c) 2014-2019 Appsicle
 *  Copyright (c) 2019-2024 QuestDB
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

package io.questdb.test.griffin.engine.functions.math;

import io.questdb.test.AbstractCairoTest;
import org.junit.Test;

public class TrigonometryTest extends AbstractCairoTest {

    @Test
    public void testSimple() throws Exception {
        assertMemoryLeak(() -> printSqlResult(
                "one\tidentity\tsin\tcos\ttan\n" +
                        "1.0\ttrue\t0.01745240643728351\t0.9998476951563913\t0.017455064928217585\n" +
                        "1.0\ttrue\t0.03489949670250097\t0.9993908270190958\t0.03492076949174773\n" +
                        "0.9999999999999999\ttrue\t0.052335956242943835\t0.9986295347545738\t0.05240777928304121\n" +
                        "0.9999999999999999\ttrue\t0.0697564737441253\t0.9975640502598242\t0.06992681194351041\n" +
                        "1.0\ttrue\t0.08715574274765817\t0.9961946980917455\t0.08748866352592401\n" +
                        "0.9999999999999999\ttrue\t0.10452846326765347\t0.9945218953682733\t0.10510423526567647\n" +
                        "0.9999999999999999\ttrue\t0.12186934340514748\t0.992546151641322\t0.1227845609029046\n" +
                        "1.0\ttrue\t0.13917310096006544\t0.9902680687415704\t0.14054083470239145\n" +
                        "1.0\ttrue\t0.15643446504023087\t0.9876883405951378\t0.15838444032453627\n" +
                        "0.9999999999999999\ttrue\t0.17364817766693033\t0.984807753012208\t0.17632698070846498\n" +
                        "1.0\ttrue\t0.1908089953765448\t0.981627183447664\t0.19438030913771848\n" +
                        "1.0\ttrue\t0.20791169081775934\t0.9781476007338057\t0.21255656167002213\n" +
                        "1.0\ttrue\t0.224951054343865\t0.9743700647852352\t0.23086819112556312\n" +
                        "1.0\ttrue\t0.24192189559966773\t0.9702957262759965\t0.24932800284318068\n" +
                        "1.0\ttrue\t0.25881904510252074\t0.9659258262890683\t0.2679491924311227\n" +
                        "1.0\ttrue\t0.27563735581699916\t0.9612616959383189\t0.2867453857588079\n" +
                        "1.0\ttrue\t0.29237170472273677\t0.9563047559630354\t0.3057306814586604\n" +
                        "0.9999999999999999\ttrue\t0.3090169943749474\t0.9510565162951535\t0.3249196962329063\n" +
                        "1.0\ttrue\t0.3255681544571567\t0.9455185755993168\t0.34432761328966527\n" +
                        "1.0\ttrue\t0.3420201433256687\t0.9396926207859084\t0.36397023426620234\n" +
                        "1.0\ttrue\t0.35836794954530027\t0.9335804264972017\t0.3838640350354158\n" +
                        "1.0\ttrue\t0.374606593415912\t0.9271838545667874\t0.4040262258351568\n" +
                        "1.0\ttrue\t0.39073112848927377\t0.9205048534524404\t0.42447481620960476\n" +
                        "0.9999999999999999\ttrue\t0.4067366430758002\t0.9135454576426009\t0.4452286853085362\n" +
                        "1.0\ttrue\t0.42261826174069944\t0.9063077870366499\t0.4663076581549986\n" +
                        "1.0\ttrue\t0.4383711467890774\t0.898794046299167\t0.48773258856586144\n" +
                        "1.0\ttrue\t0.45399049973954675\t0.8910065241883679\t0.5095254494944288\n" +
                        "1.0\ttrue\t0.4694715627858908\t0.882947592858927\t0.5317094316614788\n" +
                        "0.9999999999999999\ttrue\t0.48480962024633706\t0.8746197071393957\t0.554309051452769\n" +
                        "1.0\ttrue\t0.49999999999999994\t0.8660254037844387\t0.5773502691896257\n" +
                        "1.0\ttrue\t0.5150380749100542\t0.8571673007021123\t0.6008606190275604\n" +
                        "1.0\ttrue\t0.5299192642332049\t0.848048096156426\t0.6248693519093275\n" +
                        "1.0\ttrue\t0.5446390350150271\t0.838670567945424\t0.6494075931975106\n" +
                        "1.0\ttrue\t0.5591929034707469\t0.8290375725550416\t0.6745085168424267\n" +
                        "0.9999999999999999\ttrue\t0.573576436351046\t0.8191520442889918\t0.7002075382097097\n" +
                        "1.0\ttrue\t0.5877852522924731\t0.8090169943749475\t0.7265425280053608\n" +
                        "1.0\ttrue\t0.6018150231520483\t0.7986355100472928\t0.7535540501027942\n" +
                        "1.0\ttrue\t0.6156614753256583\t0.7880107536067219\t0.7812856265067174\n" +
                        "1.0\ttrue\t0.6293203910498374\t0.7771459614569709\t0.809784033195007\n" +
                        "0.9999999999999999\ttrue\t0.6427876096865393\t0.766044443118978\t0.8390996311772799\n" +
                        "1.0\ttrue\t0.6560590289905073\t0.754709580222772\t0.8692867378162267\n" +
                        "1.0\ttrue\t0.6691306063588582\t0.7431448254773942\t0.9004040442978399\n" +
                        "0.9999999999999999\ttrue\t0.6819983600624985\t0.7313537016191705\t0.9325150861376618\n" +
                        "1.0\ttrue\t0.6946583704589973\t0.7193398003386512\t0.9656887748070739\n" +
                        "1.0\ttrue\t0.7071067811865475\t0.7071067811865476\t0.9999999999999999\n" +
                        "1.0\ttrue\t0.7193398003386512\t0.6946583704589973\t1.0355303137905696\n" +
                        "0.9999999999999999\ttrue\t0.7313537016191705\t0.6819983600624985\t1.0723687100246826\n" +
                        "1.0\ttrue\t0.7431448254773942\t0.6691306063588582\t1.110612514829193\n" +
                        "1.0\ttrue\t0.754709580222772\t0.6560590289905073\t1.1503684072210094\n" +
                        "1.0\ttrue\t0.766044443118978\t0.6427876096865394\t1.19175359259421\n" +
                        "1.0\ttrue\t0.7771459614569709\t0.6293203910498375\t1.2348971565350515\n" +
                        "1.0\ttrue\t0.788010753606722\t0.6156614753256583\t1.2799416321930788\n" +
                        "1.0\ttrue\t0.7986355100472928\t0.6018150231520483\t1.3270448216204098\n" +
                        "1.0\ttrue\t0.8090169943749475\t0.5877852522924731\t1.3763819204711734\n" +
                        "0.9999999999999999\ttrue\t0.8191520442889918\t0.573576436351046\t1.4281480067421144\n" +
                        "1.0\ttrue\t0.8290375725550417\t0.5591929034707468\t1.4825609685127403\n" +
                        "1.0\ttrue\t0.838670567945424\t0.5446390350150271\t1.539864963814583\n" +
                        "1.0\ttrue\t0.8480480961564261\t0.5299192642332049\t1.6003345290410504\n" +
                        "1.0\ttrue\t0.8571673007021123\t0.5150380749100542\t1.6642794823505183\n" +
                        "1.0\ttrue\t0.8660254037844386\t0.5000000000000001\t1.7320508075688767\n" +
                        "1.0\ttrue\t0.8746197071393957\t0.4848096202463371\t1.8040477552714236\n" +
                        "1.0\ttrue\t0.8829475928589269\t0.46947156278589086\t1.8807264653463318\n" +
                        "1.0\ttrue\t0.8910065241883678\t0.45399049973954686\t1.9626105055051504\n" +
                        "1.0\ttrue\t0.898794046299167\t0.43837114678907746\t2.050303841579296\n" +
                        "1.0\ttrue\t0.9063077870366499\t0.42261826174069944\t2.1445069205095586\n" +
                        "0.9999999999999999\ttrue\t0.9135454576426009\t0.4067366430758002\t2.2460367739042164\n" +
                        "1.0\ttrue\t0.9205048534524404\t0.3907311284892737\t2.355852365823753\n" +
                        "1.0\ttrue\t0.9271838545667874\t0.37460659341591196\t2.4750868534162964\n" +
                        "1.0\ttrue\t0.9335804264972017\t0.3583679495453004\t2.6050890646938005\n" +
                        "0.9999999999999999\ttrue\t0.9396926207859083\t0.3420201433256688\t2.7474774194546216\n" +
                        "0.9999999999999999\ttrue\t0.9455185755993167\t0.32556815445715676\t2.904210877675822\n" +
                        "0.9999999999999999\ttrue\t0.9510565162951535\t0.30901699437494745\t3.0776835371752527\n" +
                        "1.0\ttrue\t0.9563047559630354\t0.29237170472273677\t3.2708526184841404\n" +
                        "1.0\ttrue\t0.9612616959383189\t0.27563735581699916\t3.4874144438409087\n" +
                        "1.0\ttrue\t0.9659258262890683\t0.25881904510252074\t3.7320508075688776\n" +
                        "1.0\ttrue\t0.9702957262759965\t0.24192189559966767\t4.0107809335358455\n" +
                        "1.0\ttrue\t0.9743700647852352\t0.22495105434386492\t4.331475874284157\n" +
                        "1.0\ttrue\t0.9781476007338056\t0.20791169081775945\t4.704630109478451\n" +
                        "1.0\ttrue\t0.981627183447664\t0.19080899537654492\t5.144554015970307\n" +
                        "0.9999999999999999\ttrue\t0.984807753012208\t0.17364817766693041\t5.671281819617707\n" +
                        "1.0\ttrue\t0.9876883405951378\t0.15643446504023092\t6.313751514675041\n" +
                        "1.0\ttrue\t0.9902680687415704\t0.13917310096006547\t7.115369722384207\n" +
                        "1.0\ttrue\t0.992546151641322\t0.12186934340514749\t8.144346427974593\n" +
                        "0.9999999999999999\ttrue\t0.9945218953682733\t0.10452846326765346\t9.514364454222587\n" +
                        "1.0\ttrue\t0.9961946980917455\t0.08715574274765814\t11.430052302761348\n" +
                        "0.9999999999999999\ttrue\t0.9975640502598242\t0.06975647374412523\t14.300666256711942\n" +
                        "0.9999999999999999\ttrue\t0.9986295347545738\t0.052335956242943966\t19.08113668772816\n" +
                        "1.0\ttrue\t0.9993908270190958\t0.03489949670250108\t28.636253282915515\n" +
                        "1.0\ttrue\t0.9998476951563913\t0.0174524064372836\t57.289961630759144\n" +
                        "1.0\ttrue\t1.0\t6.123233995736766E-17\t1.633123935319537E16\n",
                "with ANGLE as (select radians(x) x from long_sequence(90, 255, 255))" +
                        "    select sqrt(power(sin(x), 2) + power(cos(x), 2)) one, sin(x)/cos(x) = tan(x) identity, sin(x), cos(x), tan(x) from ANGLE",
                null,
                true,
                true));
    }

    @Test
    public void testSimpleFromTable() throws Exception {
        assertMemoryLeak(() -> {
            execute("create table angle (x double)", sqlExecutionContext);
            for (int i = 0; i <= 90; i++) {
                execute("insert into angle values(" + i * Math.PI / 180.0 + ')');
            }
            printSqlResult(
                    "angleDec\tsin\tcos\ttan\n" +
                            "true\t0.0\t1.0\t0.0\n" +
                            "true\t0.01745240643728351\t0.9998476951563913\t0.017455064928217585\n" +
                            "true\t0.03489949670250097\t0.9993908270190958\t0.03492076949174773\n" +
                            "true\t0.05233595624294383\t0.9986295347545738\t0.0524077792830412\n" +
                            "true\t0.0697564737441253\t0.9975640502598242\t0.06992681194351041\n" +
                            "true\t0.08715574274765817\t0.9961946980917455\t0.08748866352592401\n" +
                            "true\t0.10452846326765346\t0.9945218953682733\t0.10510423526567646\n" +
                            "true\t0.12186934340514748\t0.992546151641322\t0.1227845609029046\n" +
                            "true\t0.13917310096006544\t0.9902680687415704\t0.14054083470239145\n" +
                            "true\t0.15643446504023087\t0.9876883405951378\t0.15838444032453627\n" +
                            "true\t0.17364817766693033\t0.984807753012208\t0.17632698070846498\n" +
                            "true\t0.1908089953765448\t0.981627183447664\t0.19438030913771848\n" +
                            "true\t0.20791169081775931\t0.9781476007338057\t0.2125565616700221\n" +
                            "true\t0.224951054343865\t0.9743700647852352\t0.23086819112556312\n" +
                            "true\t0.24192189559966773\t0.9702957262759965\t0.24932800284318068\n" +
                            "true\t0.25881904510252074\t0.9659258262890683\t0.2679491924311227\n" +
                            "true\t0.27563735581699916\t0.9612616959383189\t0.2867453857588079\n" +
                            "true\t0.29237170472273677\t0.9563047559630354\t0.3057306814586604\n" +
                            "true\t0.3090169943749474\t0.9510565162951535\t0.3249196962329063\n" +
                            "true\t0.32556815445715664\t0.9455185755993168\t0.3443276132896652\n" +
                            "true\t0.3420201433256687\t0.9396926207859084\t0.36397023426620234\n" +
                            "true\t0.35836794954530027\t0.9335804264972017\t0.3838640350354158\n" +
                            "true\t0.374606593415912\t0.9271838545667874\t0.4040262258351568\n" +
                            "true\t0.3907311284892737\t0.9205048534524404\t0.4244748162096047\n" +
                            "true\t0.40673664307580015\t0.9135454576426009\t0.4452286853085361\n" +
                            "true\t0.42261826174069944\t0.9063077870366499\t0.4663076581549986\n" +
                            "true\t0.4383711467890774\t0.898794046299167\t0.48773258856586144\n" +
                            "true\t0.45399049973954675\t0.8910065241883679\t0.5095254494944288\n" +
                            "true\t0.4694715627858908\t0.882947592858927\t0.5317094316614788\n" +
                            "true\t0.48480962024633706\t0.8746197071393957\t0.554309051452769\n" +
                            "true\t0.49999999999999994\t0.8660254037844387\t0.5773502691896257\n" +
                            "true\t0.5150380749100542\t0.8571673007021123\t0.6008606190275604\n" +
                            "true\t0.5299192642332049\t0.848048096156426\t0.6248693519093275\n" +
                            "true\t0.5446390350150271\t0.838670567945424\t0.6494075931975106\n" +
                            "true\t0.5591929034707469\t0.8290375725550416\t0.6745085168424267\n" +
                            "true\t0.573576436351046\t0.8191520442889918\t0.7002075382097097\n" +
                            "true\t0.5877852522924731\t0.8090169943749475\t0.7265425280053608\n" +
                            "true\t0.6018150231520483\t0.7986355100472928\t0.7535540501027942\n" +
                            "true\t0.6156614753256582\t0.788010753606722\t0.7812856265067173\n" +
                            "true\t0.6293203910498374\t0.7771459614569709\t0.809784033195007\n" +
                            "true\t0.6427876096865393\t0.766044443118978\t0.8390996311772799\n" +
                            "true\t0.6560590289905072\t0.754709580222772\t0.8692867378162265\n" +
                            "true\t0.6691306063588582\t0.7431448254773942\t0.9004040442978399\n" +
                            "true\t0.6819983600624985\t0.7313537016191706\t0.9325150861376615\n" +
                            "true\t0.6946583704589973\t0.7193398003386512\t0.9656887748070739\n" +
                            "true\t0.7071067811865475\t0.7071067811865476\t0.9999999999999999\n" +
                            "true\t0.7193398003386511\t0.6946583704589974\t1.0355303137905694\n" +
                            "true\t0.7313537016191705\t0.6819983600624985\t1.0723687100246826\n" +
                            "true\t0.7431448254773942\t0.6691306063588582\t1.1106125148291928\n" +
                            "true\t0.754709580222772\t0.6560590289905073\t1.1503684072210094\n" +
                            "true\t0.766044443118978\t0.6427876096865394\t1.19175359259421\n" +
                            "true\t0.7771459614569708\t0.6293203910498375\t1.234897156535051\n" +
                            "true\t0.788010753606722\t0.6156614753256583\t1.2799416321930788\n" +
                            "true\t0.7986355100472928\t0.6018150231520483\t1.3270448216204098\n" +
                            "true\t0.8090169943749475\t0.5877852522924731\t1.3763819204711734\n" +
                            "true\t0.8191520442889918\t0.573576436351046\t1.4281480067421144\n" +
                            "true\t0.8290375725550417\t0.5591929034707468\t1.4825609685127403\n" +
                            "true\t0.8386705679454239\t0.5446390350150272\t1.5398649638145825\n" +
                            "true\t0.8480480961564261\t0.5299192642332049\t1.6003345290410504\n" +
                            "true\t0.8571673007021122\t0.5150380749100544\t1.6642794823505174\n" +
                            "true\t0.8660254037844386\t0.5000000000000001\t1.7320508075688767\n" +
                            "true\t0.8746197071393957\t0.4848096202463371\t1.8040477552714236\n" +
                            "true\t0.8829475928589269\t0.46947156278589086\t1.8807264653463318\n" +
                            "true\t0.8910065241883678\t0.45399049973954686\t1.9626105055051504\n" +
                            "true\t0.898794046299167\t0.43837114678907746\t2.050303841579296\n" +
                            "true\t0.9063077870366499\t0.42261826174069944\t2.1445069205095586\n" +
                            "true\t0.9135454576426009\t0.4067366430758002\t2.2460367739042164\n" +
                            "true\t0.9205048534524403\t0.39073112848927394\t2.355852365823752\n" +
                            "true\t0.9271838545667874\t0.37460659341591196\t2.4750868534162964\n" +
                            "true\t0.9335804264972017\t0.3583679495453004\t2.6050890646938005\n" +
                            "true\t0.9396926207859083\t0.3420201433256688\t2.7474774194546216\n" +
                            "true\t0.9455185755993167\t0.32556815445715676\t2.904210877675822\n" +
                            "true\t0.9510565162951535\t0.30901699437494745\t3.0776835371752527\n" +
                            "true\t0.9563047559630354\t0.29237170472273677\t3.2708526184841404\n" +
                            "true\t0.9612616959383189\t0.27563735581699916\t3.4874144438409087\n" +
                            "true\t0.9659258262890683\t0.25881904510252074\t3.7320508075688776\n" +
                            "true\t0.9702957262759965\t0.2419218955996679\t4.010780933535842\n" +
                            "true\t0.9743700647852352\t0.22495105434386492\t4.331475874284157\n" +
                            "true\t0.9781476007338056\t0.20791169081775945\t4.704630109478451\n" +
                            "true\t0.981627183447664\t0.19080899537654492\t5.144554015970307\n" +
                            "true\t0.984807753012208\t0.17364817766693041\t5.671281819617707\n" +
                            "true\t0.9876883405951378\t0.15643446504023092\t6.313751514675041\n" +
                            "true\t0.9902680687415703\t0.1391731009600657\t7.115369722384195\n" +
                            "true\t0.992546151641322\t0.12186934340514749\t8.144346427974593\n" +
                            "true\t0.9945218953682733\t0.10452846326765346\t9.514364454222587\n" +
                            "true\t0.9961946980917455\t0.08715574274765814\t11.430052302761348\n" +
                            "true\t0.9975640502598242\t0.06975647374412546\t14.300666256711896\n" +
                            "true\t0.9986295347545738\t0.052335956242943966\t19.08113668772816\n" +
                            "true\t0.9993908270190958\t0.03489949670250108\t28.636253282915515\n" +
                            "true\t0.9998476951563913\t0.017452406437283376\t57.289961630759876\n" +
                            "true\t1.0\t6.123233995736766E-17\t1.633123935319537E16\n",
                    "select x * 180.0/PI = degrees(x) angleDec, sin(x), cos(x), tan(x) from angle",
                    null,
                    true,
                    true);
        });
    }
}
